/** 
 * @file ppw
 * @brief PPW's DiLu Mind+ library.
 * @n This is a MindPlus graphics programming extension for PPW's DiLu intelligent vehicle.
 * 
 * @copyright    PPW,2023.09
 * @copyright    MIT Lesser General Public License
 * 
 * @author [email](info@pinpinwa.cn)
 * @date  2022-09-22
*/


//% color="#E94709" iconWith=50 iconHeight=40
namespace dilu{

    //% block="DiLu [RUN] Speed [SPEED]" blockType="command" 
    //% RUN.shadow="dropdown" RUN.options="RUN"
    //% SPEED.shadow="range" SPEED.params.min=0 SPEED.params.max=255 SPEED.defl=100

    export function DiLu_Run(parameter: any, block: any) {
        let run = parameter.RUN.code;
        let speed = parameter.SPEED.code;

        Generator.addImport("from dilu import *"); 
        Generator.addInitHeader(`initclassdilu`,`dilu = DiLu()`,true); 

        Generator.addCode(`dilu.diluRun(dilu.${run},${speed})`);        
    }

    //% block="DiLu [MOTOR] Motor Run Speed [SPEED] Dir [DIR]" blockType="command" 
    //% MOTOR.shadow="dropdown" MOTOR.options="MOTOR"
    //% SPEED.shadow="range" SPEED.params.min=0 SPEED.params.max=255 SPEED.defl=100
    //% DIR.shadow="dropdown" DIR.options="DIR"

    export function DiLu_Motorset(parameter: any, block: any) {
        let motor = parameter.MOTOR.code;
        let speed = parameter.SPEED.code;
        let dir = parameter.DIR.code;

        Generator.addImport("from dilu import *"); 
        Generator.addInitHeader(`initclassdilu`,`dilu = DiLu()`,true); 

        Generator.addCode(`dilu.motorRun(dilu.${motor},dilu.${dir},${speed})`);  
   }

   //% block="DiLu [MOTOR] Motor Stop" blockType="command"
   //% MOTOR.shadow="dropdown" MOTOR.options="MOTOR"
   export function DiLu_Motorstop(parameter:any, block:any) {
        let motor = parameter.MOTOR.code;

        Generator.addImport("from dilu import *"); 
        Generator.addInitHeader(`initclassdilu`,`dilu = DiLu()`,true); 


        Generator.addCode(`dilu.motorStop(dilu.${motor})`);
   }
    
   //% block="DiLu Servo [SERVO] Angle [ANGLE]" blockType="command"
   //% SERVO.shadow="dropdown" SERVO.options="SERVO"
   //% ANGLE.shadow="angle" ANGLE.params.edge=1
   export function DiLu_Servoangle(parameter:any, block:any) {
    let servo = parameter.SERVO.code;
    let angle = parameter.ANGLE.code;

    Generator.addImport("from dilu import *"); 
    Generator.addInitHeader(`initclassdilu`,`dilu = DiLu()`,true); 

    Generator.addCode(`dilu.servoAngle(dilu.${servo},${angle})`);
    }

   //% block="DiLu [LIGHT] LED [TOGGLE]" blockType="command"
   //% TOGGLE.shadow="dropdown" TOGGLE.options="TOGGLE"
   //% LIGHT.shadow="dropdown" LIGHT.options="LIGHT"
   export function DiLu_LED(parameter:any, block:any) {
    let toggle = parameter.TOGGLE.code;  
    let light = parameter.LIGHT.code
    
    Generator.addImport("from dilu import *"); 
    Generator.addInitHeader(`initclassdilu`,`dilu = DiLu()`,true); 
    
    Generator.addCode(`dilu.toggleLED(dilu.${light},dilu.${toggle})`);

    }

   //% block="DiLu [SIDE] Detected [STATUS]" blockType="boolean"
   //% SIDE.shadow="dropdown" SIDE.options="SIDE"
   //% STATUS.shadow="dropdown" STATUS.options="STATUS"

   export function DiLu_IRS(parameter:any, block:any) {
    let side = parameter.SIDE.code;
    let status = parameter.STATUS.code;

    Generator.addImport("from dilu import *"); 
    Generator.addInitHeader(`initclassdilu`,`dilu = DiLu()`,true); 
    Generator.addCode(`dilu.isSatus(dilu.${side},dilu.${status})`); 

   }

   //--------- 以下为巡线传感器代码块 ---------//
   //% block="DiLu Line Tracking Sensor Status [LFSTATUS]" blockType="boolean"
   //% LFSTATUS.shadow="dropdown" LFSTATUS.options="LFSTATUS"
   export function DiLu_IS_IRS(parameter:any, block:any){
    let lfstatus = parameter.LFSTATUS.code;

    Generator.addImport("from dilu import *"); 
    Generator.addInitHeader(`initclassdilu`,`dilu = DiLu()`,true); 
    Generator.addCode(`dilu.isLfStatus(dilu.${lfstatus})`); 

   }

   //--------- 以下为返回巡线传感器值代码块 ---------//
   //% block="Get Tracking Sensor Value" blockType="reporter"
   export function DiLu_GET_IRS_VALUE(parameter:any, block:any){
    //let lfvalue = parameter.LFSTATUS.code;

    Generator.addImport("from dilu import *"); 
    Generator.addInitHeader(`initclassdilu`,`dilu = DiLu()`,true); 
    Generator.addCode(`dilu.getLfValue()`); 

   }

   //--------- 以下为 C32 超声波测距模块代码块 ---------//
   //% block="Read Ultrasonic Distance [UNIT]" blockType="reporter"
   //% UNIT.shadow="dropdown" UNIT.options="UNIT"
   export function DiLu_ULTRASONIC(parameter:any, block:any){
    let unit = parameter.UNIT.code;

    Generator.addImport("from mpython import *"); 
    Generator.addImport("from hcsr04 import HCSR04"); 
    Generator.addInitHeader(`inithcsr04`,`myhcsr04 = HCSR04(trigger_pin=Pin.P1, echo_pin=Pin.P2)`); 
    
    
    if(unit == 0) {
        Generator.addCode('myhcsr04.distance_cm()');
    }
    else if(unit == 1){
        Generator.addCode('myhcsr04.distance_mm()');
    }
    
   }

   //--------- 以下为红外遥控接收代码块 ---------//
   //% block="The infrared signal is received P16 (IR_CMD)" blockType="hat"
   export function DiLu_IR_Remote(parameter:any, block:any) {

    Generator.addImport("from dilu import *"); 
    Generator.addImport("from ir_receive import IRReceiver"); 

    Generator.addInitHeader(`receiver`,`receiver = IRReceiver(Pin.P16)`); 
    Generator.addInitHeader(`receiver.daemon()`,`receiver.daemon()`); 

        
    Generator.addEvent("remote_callback","remote_callback","_address, IR_CMD");
    //Generator.addCode(`receiver.set_callback(remote_callback)`); 
    Generator.addInitHeader(`receiver.set_callback`,`receiver.set_callback(remote_callback)`);
        
   }

   //% block="IR Remote [KEY] Value" blockType="reporter"
   //% KEY.shadow="dropdown" KEY.options="20KEY_VALUE"
    export function DiLu_Remote_KEY(parameter:any, block:any){
        let value_key = parameter.KEY.code;
        Generator.addCode(`${value_key}`);
    }

   //--------- 以下为幻彩氛围灯代码块 ---------//
   //% block="RGB [LED_START]to[LED_END] Show [COLOR_PALETTE]" blockType="command"
   //% LED_START.shadow="range" LED_START.params.min=1 LED_START.params.max=4 LED_START.defl=1
   //% LED_END.shadow="range" LED_END.params.min=1 LED_END.params.max=4 LED_END.defl=1
   //% COLOR_PALETTE.shadow="colorPalette" 
   export function DiLu_Set_RangeColor(parameter:any, block:any){
    let led_start = parameter.LED_START.code;
    let led_end = parameter.LED_END.code;
    let color_palette = parameter.COLOR_PALETTE.code;



    Generator.addImport("import neopixel"); 
    Generator.addImport("from mpython import *"); 

    Generator.addInitHeader(
    `neopixel_range`,
    `def neopixel_range(rgb, start, end, color):
    trend = -1 if end < start else 1
    for i in range(start, end-1 if trend < 0 else end+1, trend):
      rgb[i] = (color)
    rgb.write()
    `);
    Generator.addInitHeader(`ws2812_P15`,`ws2812_P15 = neopixel.NeoPixel(Pin(Pin.P15), n=4, bpp=3, timing=1)`);
    
    var r = 0;
    var g = 0;
    var b = 0;
    try {
        if(color_palette.length == 8){
            r = parseInt(color_palette.substring(2,4),16);
            g = parseInt(color_palette.substring(4,6),16);
            b = parseInt(color_palette.substring(6,8),16);
            Generator.addCode(`neopixel_range(ws2812_P15,${led_start-1},${led_end-1}, (${r},${g},${b}))`); 
        }
        else{
            Generator.addCode(`neopixel_range(ws2812_P15,${led_start-1},${led_end-1}, ${color_palette})`);
        }
         catch(e) {
            return '';
        }

    } 
       
}

   //% block="RGB Clear All LEDs" blockType="command"
   export function DiLu_Clear_All_RGB(parameter:any, block:any){
    Generator.addImport("import neopixel"); 
    Generator.addImport("from mpython import *"); 

    Generator.addInitHeader(`ws2812_P15`,`ws2812_P15 = neopixel.NeoPixel(Pin(Pin.P15), n=4, bpp=3, timing=1)`);
    Generator.addCode(`ws2812_P15.fill((0, 0, 0))\nws2812_P15.write()`); 

   }


    //% block="Color Red[RVALUE] Green[GVALUE] Blue[BVALUE]" blockType="reporter"
    //% RVALUE.shadow="range" RVALUE.params.min=0 RVALUE.params.max=255 RVALUE.defl=255
    //% GVALUE.shadow="range" GVALUE.params.min=0 GVALUE.params.max=255 GVALUE.defl=255
    //% BVALUE.shadow="range" BVALUE.params.min=0 BVALUE.params.max=255 BVALUE.defl=255
    export function DiLu_RGB_VALUE(parameter:any, block:any){
        let rvalue = parameter.RVALUE.code;
        let gvalue = parameter.GVALUE.code;
        let bvalue = parameter.BVALUE.code;

        Generator.addCode(`(${rvalue},${gvalue},${bvalue})`); 
    }

}